const myNew = require("./template.js")

function testNew() {
  console.log(
    "1. 基本构造函数:",
    (() => {
      function Person(name, age) {
        this.name = name
        this.age = age
      }

      const person = myNew(Person, "Alice", 25)
      return (
        person.name === "Alice" && person.age === 25 && person instanceof Person
      )
    })()
  )

  console.log(
    "2. 无参数构造函数:",
    (() => {
      function Empty() {
        this.created = true
      }

      const instance = myNew(Empty)
      return instance.created === true && instance instanceof Empty
    })()
  )

  console.log(
    "3. 原型方法继承:",
    (() => {
      function Animal(name) {
        this.name = name
      }
      Animal.prototype.speak = function () {
        return `${this.name} makes a sound`
      }

      const animal = myNew(Animal, "Dog")
      return animal.speak() === "Dog makes a sound" && animal instanceof Animal
    })()
  )

  console.log(
    "4. 构造函数返回对象:",
    (() => {
      function CustomConstructor() {
        this.value = "ignored"
        return { custom: "returned" }
      }

      const instance = myNew(CustomConstructor)
      return (
        instance.custom === "returned" &&
        instance.value === undefined &&
        !(instance instanceof CustomConstructor)
      )
    })()
  )

  console.log(
    "5. 构造函数返回原始值:",
    (() => {
      function PrimitiveReturn() {
        this.value = "kept"
        return "ignored string"
      }

      const instance = myNew(PrimitiveReturn)
      return instance.value === "kept" && instance instanceof PrimitiveReturn
    })()
  )

  console.log(
    "6. 构造函数返回null:",
    (() => {
      function NullReturn() {
        this.value = "kept"
        return null
      }

      const instance = myNew(NullReturn)
      return instance.value === "kept" && instance instanceof NullReturn
    })()
  )

  console.log(
    "7. 嵌套对象构造:",
    (() => {
      function Outer(value) {
        this.value = value
        this.inner = myNew(Inner, value * 2)
      }

      function Inner(value) {
        this.innerValue = value
      }

      const outer = myNew(Outer, 5)
      return (
        outer.value === 5 &&
        outer.inner.innerValue === 10 &&
        outer instanceof Outer &&
        outer.inner instanceof Inner
      )
    })()
  )

  console.log(
    "8. 类构造函数:",
    (() => {
      class MyClass {
        constructor(value) {
          this.value = value
        }

        getValue() {
          return this.value
        }
      }

      const instance = myNew(MyClass, 42)
      return (
        instance.value === 42 &&
        instance.getValue() === 42 &&
        instance instanceof MyClass
      )
    })()
  )

  console.log(
    "9. 继承类构造:",
    (() => {
      class Parent {
        constructor(name) {
          this.name = name
        }
      }

      class Child extends Parent {
        constructor(name, age) {
          super(name)
          this.age = age
        }
      }

      const child = myNew(Child, "Alice", 10)
      return (
        child.name === "Alice" &&
        child.age === 10 &&
        child instanceof Child &&
        child instanceof Parent
      )
    })()
  )

  console.log(
    "10. 多个参数传递:",
    (() => {
      function MultiParam(a, b, c, d, e) {
        this.sum = a + b + c + d + e
        this.args = [a, b, c, d, e]
      }

      const instance = myNew(MultiParam, 1, 2, 3, 4, 5)
      return (
        instance.sum === 15 &&
        JSON.stringify(instance.args) === JSON.stringify([1, 2, 3, 4, 5])
      )
    })()
  )

  console.log(
    "11. 构造函数this指向:",
    (() => {
      function CheckThis() {
        this.isCorrectThis = this instanceof CheckThis
      }

      const instance = myNew(CheckThis)
      return instance.isCorrectThis === true
    })()
  )

  console.log(
    "12. 数组构造函数:",
    (() => {
      const arr = myNew(Array, 1, 2, 3)
      return (
        arr.length === 3 &&
        arr[0] === 1 &&
        arr[1] === 2 &&
        arr[2] === 3 &&
        arr instanceof Array
      )
    })()
  )

  console.log(
    "13. 对象构造函数:",
    (() => {
      const obj = myNew(Object, { a: 1, b: 2 })
      return obj.a === 1 && obj.b === 2 && obj instanceof Object
    })()
  )

  console.log(
    "14. 函数构造函数:",
    (() => {
      const fn = myNew(Function, "a", "b", "return a + b")
      return (
        typeof fn === "function" && fn(2, 3) === 5 && fn instanceof Function
      )
    })()
  )

  console.log(
    "15. 错误构造函数:",
    (() => {
      const error = myNew(Error, "Test message")
      return error.message === "Test message" && error instanceof Error
    })()
  )

  console.log(
    "16. 日期构造函数:",
    (() => {
      const date = myNew(Date, 2023, 0, 1) // 2023年1月1日
      return (
        date instanceof Date &&
        date.getFullYear() === 2023 &&
        date.getMonth() === 0
      )
    })()
  )

  console.log(
    "17. 正则表达式构造函数:",
    (() => {
      const regex = myNew(RegExp, "test", "gi")
      return (
        regex instanceof RegExp &&
        regex.source === "test" &&
        regex.flags.includes("g") &&
        regex.flags.includes("i")
      )
    })()
  )

  console.log(
    "18. 构造函数属性添加:",
    (() => {
      function WithProperties() {
        this.prop1 = "value1"
        this.prop2 = "value2"
      }
      WithProperties.staticProp = "static"

      const instance = myNew(WithProperties)
      return (
        instance.prop1 === "value1" &&
        instance.prop2 === "value2" &&
        instance.staticProp === undefined
      ) // 静态属性不会继承
    })()
  )

  console.log(
    "19. 复杂原型链:",
    (() => {
      function GrandParent() {
        this.level = "grandparent"
      }
      GrandParent.prototype.getLevel = function () {
        return this.level
      }

      function Parent() {
        GrandParent.call(this)
        this.level = "parent"
      }
      Parent.prototype = Object.create(GrandParent.prototype)

      const parent = myNew(Parent)
      return (
        parent.level === "parent" &&
        parent.getLevel() === "parent" &&
        parent instanceof Parent &&
        parent instanceof GrandParent
      )
    })()
  )

  console.log(
    "20. 与原生new对比:",
    (() => {
      function TestConstructor(value) {
        this.value = value
        this.timestamp = Date.now()
      }
      TestConstructor.prototype.getValue = function () {
        return this.value
      }

      const myInstance = myNew(TestConstructor, "test")
      const nativeInstance = new TestConstructor("test")

      return (
        myInstance.value === nativeInstance.value &&
        typeof myInstance.timestamp === "number" &&
        myInstance.getValue() === nativeInstance.getValue() &&
        myInstance instanceof TestConstructor &&
        nativeInstance instanceof TestConstructor
      )
    })()
  )

  console.log(
    "21. 非函数构造器错误:",
    (() => {
      try {
        myNew({}, "invalid")
        return false // 应该抛出错误
      } catch (e) {
        return true // 正确抛出错误
      }
    })()
  )

  console.log(
    "22. Symbol作为构造函数:",
    (() => {
      try {
        myNew(Symbol, "test")
        return false // Symbol不能作为构造函数
      } catch (e) {
        return true // 正确抛出错误
      }
    })()
  )
}

testNew()
